/**
 * Pinia Store - 实时数据管理
 * 管理所有WebSocket数据源的实时数据（测点/标签）
 */

import { defineStore } from 'pinia';
import { ref, computed, reactive } from 'vue';
import type { WSMessage, DataSource } from '@/services/websocket';
import { MessageParser } from '@/utils/message-parser';

// 数据点接口定义
export interface DataPoint {
  id: string; // 数据点唯一标识
  name: string; // 数据点名称
  value: any; // 当前值
  type: string; // 数据类型：number, string, boolean, object
  unit?: string; // 单位
  timestamp: number; // 最后更新时间
  sourceId: string; // 数据源ID
  quality: 'good' | 'bad' | 'uncertain'; // 数据质量
  description?: string; // 描述
}

// 数据源连接状态
export interface DataSourceStatus {
  id: string;
  name: string;
  status: 'connected' | 'disconnected' | 'connecting' | 'error';
  lastUpdate: number;
  messageCount: number;
  errorCount: number;
}

export const useRealtimeDataStore = defineStore('realtimeData', () => {
  // 所有数据点的Map，key为数据点ID
  const dataPoints = reactive(new Map<string, DataPoint>());

  // 数据源状态Map
  const sourceStatus = reactive(new Map<string, DataSourceStatus>());

  // 数据源配置缓存（包含解析规则）
  const dataSourceConfigs = reactive(new Map<string, DataSource>());

  // 消息数据缓存（用于路径式查询）
  const messageDataCache = reactive(new Map<string, any>());

  // 历史数据缓存（可选，用于趋势图等）
  const historyData = reactive(new Map<string, Array<{ value: any; timestamp: number }>>());

  // 订阅者Map，用于组件订阅特定数据点
  const subscribers = reactive(new Map<string, Set<string>>());

  /**
   * 路径解析工具：从消息数据中按路径提取值
   */
  const extractValueByPath = (data: any, path: string): any => {
    if (!path || path === '$' || path === '.') {
      return data;
    }

    // 处理JSONPath格式
    if (path.startsWith('$.')) {
      path = path.substring(2);
    } else if (path.startsWith('$')) {
      path = path.substring(1);
    }

    // 处理data.前缀的路径格式
    if (path.startsWith('data.')) {
      // 移除data.前缀，继续解析剩余路径
      const remainingPath = path.substring('data.'.length);

      // 对于 data.实时.xxx 格式，尝试多种解析方式
      if (remainingPath.startsWith('实时.')) {
        const realPropertyName = remainingPath.substring('实时.'.length);

        // 方式1: 直接从扁平数据中查找属性
        if (data && typeof data === 'object' && data[realPropertyName] !== undefined) {
          return data[realPropertyName];
        }

        // 方式2: 尝试在嵌套结构中查找
        if (data && typeof data === 'object') {
          // 2.1 检查是否有 "实时" 属性
          if (
            data['实时'] &&
            typeof data['实时'] === 'object' &&
            data['实时'][realPropertyName] !== undefined
          ) {
            return data['实时'][realPropertyName];
          }

          // 2.2 递归搜索所有嵌套对象中的目标属性
          const searchInObject = (obj: any, targetKey: string): any => {
            if (!obj || typeof obj !== 'object') return undefined;

            // 直接查找
            if (obj[targetKey] !== undefined) {
              return obj[targetKey];
            }

            // 递归查找
            for (const key in obj) {
              if (typeof obj[key] === 'object' && obj[key] !== null) {
                const result = searchInObject(obj[key], targetKey);
                if (result !== undefined) {
                  return result;
                }
              }
            }
            return undefined;
          };

          const nestedResult = searchInObject(data, realPropertyName);
          if (nestedResult !== undefined) {
            return nestedResult;
          }
        }
      }

      // 对于其他data.xxx.yyy.zzz格式，使用通用dot notation解析
      path = remainingPath;
    }

    // 简单的dot notation解析
    const parts = path.split('.');
    let current = data;

    for (const part of parts) {
      if (current === null || current === undefined) {
        return undefined;
      }

      // 处理数组索引
      if (part.includes('[') && part.includes(']')) {
        const [key, indexStr] = part.split('[');
        const index = parseInt(indexStr.replace(']', ''));
        current = current[key];
        if (Array.isArray(current) && index >= 0 && index < current.length) {
          current = current[index];
        } else {
          return undefined;
        }
      } else {
        current = current[part];
      }
    }

    return current;
  };

  /**
   * 根据路径式数据点ID获取值
   */
  const getValueByPathId = (pathId: string, sourceId?: string): any => {
    // 如果没有指定数据源，尝试从所有数据源中查找
    if (!sourceId) {
      for (const [sid, data] of messageDataCache) {
        const value = extractValueByPath(data, pathId);
        if (value !== undefined) {
          return { value, sourceId: sid };
        }
      }
      return { value: undefined, sourceId: null };
    }

    const data = messageDataCache.get(sourceId);
    if (!data) {
      return { value: undefined, sourceId };
    }

    const value = extractValueByPath(data, pathId);
    return { value, sourceId };
  };

  /**
   * 更新数据点
   */
  const updateDataPoint = (point: Partial<DataPoint> & { id: string }) => {
    const existing = dataPoints.get(point.id);
    const now = Date.now();

    const updatedPoint: DataPoint = {
      id: point.id,
      name: point.name || existing?.name || point.id,
      value: point.value,
      type: point.type || typeof point.value,
      unit: point.unit || existing?.unit,
      timestamp: now,
      sourceId: point.sourceId || existing?.sourceId || 'unknown',
      quality: point.quality || 'good',
      description: point.description || existing?.description
    };

    dataPoints.set(point.id, updatedPoint);

    // 更新历史数据（保留最近100条）
    if (!historyData.has(point.id)) {
      historyData.set(point.id, []);
    }
    const history = historyData.get(point.id)!;
    history.push({ value: point.value, timestamp: now });
    if (history.length > 100) {
      history.shift();
    }
  };

  /**
   * 批量更新数据点
   */
  const updateDataPoints = (points: Array<Partial<DataPoint> & { id: string }>) => {
    points.forEach((point) => updateDataPoint(point));
  };

  /**
   * 获取数据点（支持路径式ID）
   */
  const getDataPoint = (id: string): DataPoint | undefined => {
    let dataPoint = dataPoints.get(id);

    // 如果数据点不存在且ID包含路径格式，尝试创建路径式数据点
    if (!dataPoint && id.includes('.')) {
      const result = getValueByPathId(id);
      if (result.value !== undefined) {
        updateDataPoint({
          id: id,
          value: result.value,
          sourceId: result.sourceId || 'unknown',
          quality: 'good',
          description: `路径: ${id}`
        });
        dataPoint = dataPoints.get(id);
      }
    }

    return dataPoint;
  };

  /**
   * 获取数据点的值（支持路径式ID）
   */
  const getDataValue = (id: string): any => {
    const dataPoint = dataPoints.get(id);

    // 如果数据点不存在且ID包含路径格式，直接从缓存中查询
    if (!dataPoint && id.includes('.')) {
      const result = getValueByPathId(id);
      if (result.value !== undefined) {
        // 自动创建数据点
        updateDataPoint({
          id: id,
          value: result.value,
          sourceId: result.sourceId || 'unknown',
          quality: 'good',
          description: `路径: ${id}`
        });
        return result.value;
      }
    }

    return dataPoint?.value;
  };

  /**
   * 获取数据点的历史数据
   */
  const getHistoryData = (id: string): Array<{ value: any; timestamp: number }> => {
    return historyData.get(id) || [];
  };

  /**
   * 订阅数据点变化
   */
  const subscribe = (pointId: string, subscriberId: string) => {
    if (!subscribers.has(pointId)) {
      subscribers.set(pointId, new Set());
    }
    subscribers.get(pointId)!.add(subscriberId);
  };

  /**
   * 取消订阅
   */
  const unsubscribe = (pointId: string, subscriberId: string) => {
    const subs = subscribers.get(pointId);
    if (subs) {
      subs.delete(subscriberId);
      if (subs.size === 0) {
        subscribers.delete(pointId);
      }
    }
  };

  /**
   * 更新数据源配置
   */
  const updateDataSourceConfig = (dataSource: DataSource) => {
    dataSourceConfigs.set(dataSource.id, dataSource);
  };

  /**
   * 批量更新数据源配置
   */
  const updateDataSourceConfigs = (dataSources: DataSource[]) => {
    dataSources.forEach((ds) => updateDataSourceConfig(ds));
  };

  /**
   * 获取数据源配置
   */
  const getDataSourceConfig = (sourceId: string): DataSource | undefined => {
    return dataSourceConfigs.get(sourceId);
  };

  /**
   * 处理WebSocket消息
   */
  const handleWebSocketMessage = (message: WSMessage) => {
    try {
      // 更新数据源状态
      updateSourceStatus({
        id: message.source || 'unknown',
        status: 'connected',
        lastUpdate: message.timestamp || Date.now()
      });

      // 根据消息类型处理数据
      switch (message.type) {
        case 'data':
        case 'update':
          handleDataMessage(message);
          break;
        case 'batch':
          handleBatchMessage(message);
          break;
        case 'heartbeat':
          // 心跳消息，只更新连接状态
          break;
        default:
      }
    } catch (error) {
      console.error('Error handling WebSocket message:', error);
      updateSourceStatus({
        id: message.source || 'unknown',
        errorCount: (getSourceStatus(message.source || 'unknown')?.errorCount || 0) + 1
      });
    }
  };

  /**
   * 检查数据是否有效（包含有意义的属性）
   */
  const isValidData = (data: any): boolean => {
    if (!data || typeof data !== 'object') {
      return false;
    }

    // 检查是否为空对象
    const keys = Object.keys(data);
    if (keys.length === 0) {
      return false;
    }

    // 检查是否包含有效的值（不全是null/undefined）
    const values = Object.values(data);
    const validValues = values.filter((v) => v !== null && v !== undefined);

    if (validValues.length === 0) {
      return false;
    }

    // 如果只有action、type、timestamp等元数据字段，不算有效数据
    const metadataOnlyKeys = ['action', 'type', 'timestamp', 'source', 'id'];
    const dataKeys = keys.filter((key) => !metadataOnlyKeys.includes(key));

    return dataKeys.length > 0;
  };

  /**
   * 处理单个数据消息 - 只缓存有效数据
   */
  const handleDataMessage = (message: WSMessage) => {
    const sourceId = message.source || 'unknown';

    try {
      // 只缓存有效的消息数据
      if (message.data && isValidData(message.data)) {
        messageDataCache.set(sourceId, message.data);
        // 通知所有使用路径式数据点ID的订阅者更新数据
        refreshPathBasedDataPoints(sourceId);
      }
    } catch (error) {
      console.error('Error handling data message:', error);
    }
  };

  /**
   * 刷新路径式数据点的值
   */
  const refreshPathBasedDataPoints = (sourceId: string) => {
    // 遍历所有现有数据点，更新使用路径格式的数据点
    dataPoints.forEach((dataPoint, pointId) => {
      // 检查是否是路径式数据点ID（包含点号）
      if (
        pointId.includes('.') &&
        (dataPoint.sourceId === sourceId || dataPoint.sourceId === 'unknown')
      ) {
        const result = getValueByPathId(pointId, sourceId);
        if (result.value !== undefined) {
          updateDataPoint({
            id: pointId,
            value: result.value,
            sourceId: sourceId,
            quality: 'good',
            description: `路径: ${pointId}`
          });
        }
      }
    });

    // 检查所有订阅者，为他们创建可能缺失的数据点
    subscribers.forEach((subscriberSet, pointId) => {
      if (pointId.includes('.') && !dataPoints.has(pointId)) {
        const result = getValueByPathId(pointId, sourceId);
        if (result.value !== undefined) {
          updateDataPoint({
            id: pointId,
            value: result.value,
            sourceId: sourceId,
            quality: 'good',
            description: `路径: ${pointId}`
          });
        }
      }
    });
  };

  /**
   * 处理批量数据消息
   */
  const handleBatchMessage = (message: WSMessage) => {
    const data = message.data;

    if (Array.isArray(data)) {
      const points = data.map((item) => ({
        id: item.id || item.tagId || item.pointId || `${message.source}_${Math.random()}`,
        name: item.name || item.tagName,
        value: item.value,
        type: item.type,
        unit: item.unit,
        sourceId: message.source,
        quality: item.quality || 'good',
        description: item.description
      }));

      updateDataPoints(points);
    }
  };

  /**
   * 更新数据源状态
   */
  const updateSourceStatus = (status: Partial<DataSourceStatus> & { id: string }) => {
    const existing = sourceStatus.get(status.id);
    const now = Date.now();

    const updatedStatus: DataSourceStatus = {
      id: status.id,
      name: status.name || existing?.name || status.id,
      status: status.status || existing?.status || 'disconnected',
      lastUpdate: status.lastUpdate || now,
      messageCount: existing?.messageCount || 0,
      errorCount: status.errorCount || existing?.errorCount || 0
    };

    // 如果收到消息，增加消息计数
    if (status.lastUpdate || status.status === 'connected') {
      updatedStatus.messageCount = (existing?.messageCount || 0) + 1;
    }

    sourceStatus.set(status.id, updatedStatus);
  };

  /**
   * 获取数据源状态
   */
  const getSourceStatus = (sourceId: string): DataSourceStatus | undefined => {
    return sourceStatus.get(sourceId);
  };

  /**
   * 清理指定数据源的数据
   */
  const clearSourceData = (sourceId: string) => {
    // 删除该数据源的所有数据点
    for (const [pointId, point] of dataPoints) {
      if (point.sourceId === sourceId) {
        dataPoints.delete(pointId);
        historyData.delete(pointId);
        subscribers.delete(pointId);
      }
    }

    // 删除数据源状态
    sourceStatus.delete(sourceId);
  };

  /**
   * 清空所有数据
   */
  const clearAllData = () => {
    dataPoints.clear();
    historyData.clear();
    sourceStatus.clear();
    subscribers.clear();
    messageDataCache.clear();
  };

  /**
   * 清理无效的缓存数据
   */
  const cleanInvalidCache = () => {
    const toDelete: string[] = [];

    for (const [sourceId, data] of messageDataCache) {
      if (!isValidData(data)) {
        toDelete.push(sourceId);
      }
    }

    toDelete.forEach((sourceId) => {
      messageDataCache.delete(sourceId);
    });

    return toDelete.length;
  };

  /**
   * 获取缓存的消息数据
   */
  const getCachedMessageData = (sourceId: string) => {
    return messageDataCache.get(sourceId);
  };

  /**
   * 获取所有缓存的消息数据（响应式）
   */
  const getAllCachedMessageData = () => {
    return messageDataCache;
  };

  /**
   * 验证路径式数据点ID是否有效
   */
  const validatePathId = (pathId: string, sourceId?: string): boolean => {
    const result = getValueByPathId(pathId, sourceId);
    return result.value !== undefined;
  };

  // 计算属性
  const connectedSources = computed(() => {
    return Array.from(sourceStatus.values()).filter((s) => s.status === 'connected');
  });

  const totalDataPoints = computed(() => {
    return dataPoints.size;
  });

  const recentDataPoints = computed(() => {
    return Array.from(dataPoints.values())
      .sort((a, b) => b.timestamp - a.timestamp)
      .slice(0, 10);
  });

  return {
    // 状态
    dataPoints: computed(() => Array.from(dataPoints.values())),
    sourceStatus: computed(() => Array.from(sourceStatus.values())),
    connectedSources,
    totalDataPoints,
    recentDataPoints,

    // 方法
    updateDataPoint,
    updateDataPoints,
    getDataPoint,
    getDataValue,
    getHistoryData,
    subscribe,
    unsubscribe,
    handleWebSocketMessage,
    updateSourceStatus,
    getSourceStatus,
    clearSourceData,
    clearAllData,

    // 数据源配置管理
    updateDataSourceConfig,
    updateDataSourceConfigs,
    getDataSourceConfig,

    // 路径式数据点支持
    getCachedMessageData,
    getAllCachedMessageData,
    validatePathId,
    getValueByPathId,
    extractValueByPath,
    refreshPathBasedDataPoints,

    // 数据验证和清理
    isValidData,
    cleanInvalidCache
  };
});
